home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / modem.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  5KB  |  227 lines

  1. /* modem - Put modem into DIALIN or DIALOUT mode.    Author: F. van Kempen */
  2.  
  3. /* Exit:    1    OK, suspended/restarted GETTY
  4.  *        0    Error, GETTY would not listen
  5.  *        -1    Error in UTMP file
  6.  *        -2    TTY not found
  7.  *        -3    Process not GETTY
  8.  *        -4    Process busy
  9.  *        -5    Unknown process type
  10.  *
  11.  * Version:    1.3     12/30/89
  12.  *
  13.  * Author:    F. van Kempen, MicroWalt Corporation
  14.  */
  15.  
  16. #include <sys/types.h>
  17. #include <fcntl.h>
  18. #include <sgtty.h>
  19. #include <signal.h>
  20. #include <string.h>
  21. #include <utmp.h>
  22.  
  23. static char *Version = "@(#) MODEM 1.3 (12/30/89)";
  24. int debug = 0;            /* generate some debugging output */
  25. int rings = -999;        /* number of rings for dial-in */
  26.  
  27.  
  28. extern char *itoa();
  29.  
  30.  
  31. /* Tell modem to go into DIAL-IN mode.
  32.  * We do this by resetting it and by setting the
  33.  * S0-register to a positive value.
  34.  */
  35. int dialin(tty)
  36. char *tty;
  37. {
  38.   struct sgttyb old, new;
  39.   char buff[32];
  40.   int fd;
  41.  
  42.   /* Create file name of modem. */
  43.   strcpy(buff, "/dev/");
  44.   strcat(buff, tty);
  45.  
  46.   /* open the device */
  47.   fd = open(buff, O_RDWR);
  48.   if (fd < 0) return(0);
  49.  
  50.   /* Get old terminal status. */
  51.   ioctl(fd, TIOCGETP, &old);
  52.  
  53.   /* Set temporary parameters. This equals 'stty sane 1200'. */
  54.   ioctl(fd, TIOCGETP, &new);
  55.   new.sg_ispeed = B1200;
  56.   new.sg_ospeed = B1200;
  57.   new.sg_flags = (BITS8 | CRMOD | XTABS);
  58.   ioctl(fd, TIOCSETP, &new);
  59.  
  60.   /* Say hello to the modem. */
  61.   write(fd, "+++", 3);
  62.   sleep(2);
  63.  
  64.   /* Reset the modem. */
  65.   write(fd, "AT Z\n", 5);  
  66.   sleep(1);
  67.  
  68.   /* Create the ANSWER string. */
  69.   strcpy(buff, "AT S0=");
  70.   strcat(buff, itoa(rings));
  71.   strcat(buff, "\n");
  72.   write(fd, buff, strlen(buff));
  73.  
  74.   /* Restore the old terminal parameters. */
  75.   ioctl(fd, TIOCSETP, &old);
  76.  
  77.   close(fd);
  78.   return(1);
  79. }
  80.  
  81.  
  82. /* Tell modem to go into DIAL-OUT mode.
  83.  * We do this by resetting it and by setting the
  84.  * S0-register to a zero (zero rings!).
  85.  */
  86. int dialout(tty)
  87. char *tty;
  88. {
  89.   struct sgttyb old, new;
  90.   char buff[32];
  91.   int fd;
  92.  
  93.   /* create file name of modem */
  94.   strcpy(buff, "/dev/");
  95.   strcat(buff, tty);
  96.  
  97.   /* open the device */
  98.   fd = open(buff, O_RDWR);
  99.   if (fd < 0) return(0);
  100.  
  101.   /* Get old terminal status. */
  102.   ioctl(fd, TIOCGETP, &old);
  103.  
  104.   /* Set temporary parameters. This equals 'stty sane 1200'. */
  105.   ioctl(fd, TIOCGETP, &new);
  106.   new.sg_ispeed = B1200;
  107.   new.sg_ospeed = B1200;
  108.   new.sg_flags = (BITS8 | CRMOD | XTABS);
  109.   ioctl(fd, TIOCSETP, &new);
  110.  
  111.   /* Say hello to the modem. */
  112.   write(fd, "+++", 3);
  113.   sleep(2);
  114.  
  115.   /* Reset the modem. */
  116.   write(fd, "AT Z\n", 5);  
  117.   sleep(1);
  118.  
  119.   /* Send the NO-ANSWER string. */
  120.   write(fd, "AT S0=0\n", 8);
  121.  
  122.   /* Restore the old terminal parameters. */
  123.   ioctl(fd, TIOCSETP, &old);
  124.  
  125.   close(fd);
  126.   return(1);
  127. }
  128.  
  129.  
  130. void usage()
  131. {
  132.    write(2, "Usage: modem [-d] [-g] <-i rings | -o> line\n", 44);
  133.   exit(-1);
  134. }
  135.  
  136.  
  137. main(argc, argv)
  138. int argc;
  139. char *argv[];
  140. {
  141.   struct utmp entry;
  142.   char *tty, *s;
  143.   int fd, st;
  144.  
  145.   st = 0;
  146.   while (st < argc) {
  147.     s = argv[++st];
  148.     if (s && *s == '-') switch (*++s) {
  149.             case 'd':    /* DEBUG mode */
  150.             debug = 1;
  151.             break;
  152.             case 'g':    /* GETTY mode */
  153.             rings = -1;
  154.             break;
  155.             case 'i':    /* DIAL-IN mode: suspend GETTY and
  156.                  * call modem */
  157.             s++;
  158.             if (*s != '\0')
  159.                 rings = atoi(s);
  160.             else
  161.                 rings = atoi(argv[++st]);
  162.             break;
  163.             case 'o':    /* DIAL-OUT mode: restart GETTY and
  164.                  * call modem */
  165.             rings = 0;
  166.             break;
  167.             default:
  168.             usage();
  169.     } else
  170.         break;
  171.   }
  172.  
  173.   if (rings == -999) usage();    /* badly formed parameters! */
  174.  
  175.   if (st >= argc) usage();    /* we need the TTY name as well! */
  176.   tty = argv[st];        /* get the terminal name */
  177.  
  178.   /* Read the UTMP file to find out the PID and STATUS of the GETTY. */
  179.   if ((fd = open(UTMP, O_RDONLY)) < 0) {
  180.     write(2, "modem: cannot open UTMP !\n", 26);
  181.     exit(-1);
  182.   }
  183.   while (read(fd, &entry, sizeof(struct utmp)) == sizeof(struct utmp)) {
  184.     if (!strcmp(entry.ut_line, tty)) {
  185.         close(fd);
  186.         tty = entry.ut_line;
  187.         fd = -1;
  188.         break;
  189.     }
  190.   }
  191.   close(fd);
  192.  
  193.   /* Process the terminal entry if we got one. */
  194.   if (fd == -1) switch (entry.ut_type) {
  195.         case INIT_PROCESS:        /* this is not a tty-process! */
  196.         if (debug)
  197.             write(2, "modem: no TTY-servicing process!\n", 33);
  198.         exit(-3);
  199.         case LOGIN_PROCESS:        /* getty waiting for a call */
  200.         break;
  201.         case USER_PROCESS:        /* login or user-shell */
  202.         if (debug) write(2, "modem: line is busy.\n", 21);
  203.         exit(-4);
  204.         break;
  205.         default:
  206.         if (debug) write(2, "modem: unknown UTMP entry\n", 26);
  207.         exit(-5);
  208.   } else
  209.     exit(-2);
  210.  
  211.   /* Now perform the desired action (DIALIN or DIALOUT). */
  212.   switch (rings) {
  213.       case -1:                /* -1 means "plain GETTY" */
  214.     kill(entry.ut_pid, SIGBUS);    /* send IGNORE signal */
  215.     st = 0;
  216.     break;
  217.       case 0:
  218.     kill(entry.ut_pid, SIGEMT);    /* send SUSPEND signal */
  219.     st = dialout(tty);        /* put MODEM into DIALOUT */
  220.     break;
  221.       default:
  222.     kill(entry.ut_pid, SIGIOT);    /* send RESTART signal */
  223.     st = dialin(tty);        /* put MODEM in DIALIN */
  224.   }
  225.   exit(st);
  226. }
  227.